#include "stdafx.h"
#include "FileParse.h"

//////////////////////////////////////////////////////////////////////////
// file parse
bool CMFCFileParse::LoadData(PointVect& points,LPCSTR strFileName)
{
	if(strFileName == NULL)
		return false;

	CFile file;
	if( !file.Open( strFileName, CFile::modeRead ) )
		return FALSE;
	CArchive ar(&file,CArchive::load);
	CString str;
	points.clear();
	Point2D temp;
	while (ar.ReadString(str))
	{
		if(sscanf(str,"%lf %lf", &temp.x,&temp.y))
			points.push_back(temp);
	}
	ar.Close();
	file.Close();

	return true;
}

bool CMFCFileParse::SaveData(PointVect& points,LPCSTR strFileName)
{
	if(strFileName == NULL)
		return false;
	
	CFile file;
	if( !file.Open( strFileName, CFile::modeWrite|CFile::modeCreate ) )
		return FALSE;
	CArchive ar(&file,CArchive::store);
	IterPointVect iter = points.begin();
	CString str;
	while (iter != points.end())
	{
		str.Format("%lf %lf\n",iter->x,iter->y);
		ar.WriteString(LPCSTR(str));
		iter ++;
	}
	
	ar.Close();
	file.Close();
	
	return true;
}

bool CSTLFileParse::LoadData(PointVect& points,LPCSTR strFileName)
{
	if(strFileName == NULL)
		return false;
	
	std::ifstream infile(strFileName);
	if(!infile)
		return false;

	points.clear();
	std::copy(std::istream_iterator<Point2D>(infile),std::istream_iterator<Point2D>(),std::back_inserter(points));

	infile.close();

	return true;
}

bool CSTLFileParse::SaveData(PointVect& points,LPCSTR strFileName)
{
	if(strFileName == NULL)
		return false;
	
	std::ofstream outfile(strFileName);
	if(!outfile)
		return false;
	
	std::copy(points.begin(),points.end(),std::ostream_iterator<Point2D>(outfile));
	
	outfile.close();
	
	return true;
}

bool CMAPFileParse::LoadData(PointVect& points,LPCSTR strFileName)
{
	if(strFileName == NULL)
		return false;
	
	HANDLE hFile = CreateFile(strFileName,GENERIC_WRITE|GENERIC_READ,0,NULL
		,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if(hFile == INVALID_HANDLE_VALUE)
	{
		printf("File could not be opened.");
		return FALSE;
	}
	
	DWORD dwFileSize = GetFileSize(hFile,NULL);
	
	HANDLE hFileMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,
		dwFileSize+sizeof(char),NULL);
	
	if(hFileMap == NULL){
		CloseHandle(hFile);
		return FALSE;
	}
	
	PVOID pvFile = MapViewOfFile(hFileMap,FILE_MAP_WRITE,0,0,0);
	
	if(pvFile == NULL){
		CloseHandle(hFileMap);
		CloseHandle(hFile);
		return FALSE;
	}
	
	PSTR pchAnsi = (PSTR)pvFile; 
	pchAnsi[dwFileSize/sizeof(char)]=0;
	PSTR pchAnsi2 = NULL;
	char buf[1000];
	
	points.clear();
	
	pchAnsi2 = strchr(pchAnsi,'\n');
	Point2D temp;
	while(pchAnsi2 != NULL){
		strncpy(buf,pchAnsi,pchAnsi2 - pchAnsi);
		std::istrstream istrinf(buf);
		istrinf >> temp.x >> temp.y;
		points.push_back(temp);
		pchAnsi = pchAnsi2 + 1;
		pchAnsi2 = strchr(pchAnsi,'\n');	
	}
	
	UnmapViewOfFile(pvFile);
	CloseHandle(hFileMap);
	CloseHandle(hFile);

	return true;
}

bool CMAPFileParse::SaveData(PointVect& points,LPCSTR strFileName)
{
	if(strFileName == NULL)
		return false;
	
	CFile file;
	if( !file.Open( strFileName, CFile::modeWrite|CFile::modeCreate ) )
		return FALSE;
	CArchive ar(&file,CArchive::store);
	IterPointVect iter = points.begin();
	while (iter != points.end())
	{
		ar << iter->x << ' ' << iter->y << '\n';
		iter ++;
	}
	
	file.Close();
	
	return true;
}

//////////////////////////////////////////////////////////////////////////
// my data
void CFPData::DrawVertexs(CDC* pDC)
{
	std::for_each(vertexs.begin(),vertexs.end(),Point2D::drawPoint2D(*pDC));
}

bool CFPData::LoadData(LPCSTR strFileName,int nloadStyle)
{
	CFileParse* pFileParse = NULL;
	bool bret = true;

	switch(nloadStyle) {
	case FILE_PARSE_MFC:
		pFileParse = new CMFCFileParse();
		bret = pFileParse->LoadData(vertexs,strFileName);
		break;
	case FILE_PARSE_STL:
		pFileParse = new CSTLFileParse();
		bret = pFileParse->LoadData(vertexs,strFileName);
		break;
	case FILE_PARSE_MAP:
		pFileParse = new CMAPFileParse();
		bret = pFileParse->LoadData(vertexs,strFileName);
		break;
	default:
		break;
	}
	delete pFileParse;

	return bret;
}

bool CFPData::SaveData(LPCSTR strFileName,int nloadStyle)
{
	CFileParse* pFileParse = NULL;
	bool bret = true;
	
	switch(nloadStyle) {
	case FILE_PARSE_MFC:
		pFileParse = new CMFCFileParse();
		bret = pFileParse->SaveData(vertexs,strFileName);
		break;
	case FILE_PARSE_STL:
		pFileParse = new CSTLFileParse();
		bret = pFileParse->SaveData(vertexs,strFileName);
		break;
	case FILE_PARSE_MAP:
		pFileParse = new CMAPFileParse();
		bret = pFileParse->SaveData(vertexs,strFileName);
		break;
	default:
		break;
	}
	delete pFileParse;
	
	return bret;
}

void CFPData::CreatRandData(int nPNum,CRect& rect)
{
	int xmax = rect.right;
	int ymax = rect.bottom;

	Point2D temp;

	vertexs.clear();
	for(int i = 0; i < nPNum; i ++)
	{
		temp.x = rand() % xmax;
		temp.y = rand() % ymax;
		vertexs.push_back(temp);
	}
}
